/*
 * Tuple.cpp
 *
 *  Created on: 06/02/2014
 *      Author: Bruno
 */

#include "Tuple.h"
#include <iostream>

using namespace std;

int Tuple::tuplesIntSize = 0;
int Tuple::tuplesLength = 0;

//modes -> array[0 : tuplesLength-1]
//times -> array[tuplesLength : 2*tuplesLength-1]
//partialTimes -> array[2*tuplesLength : 3*tuplesLength-1]
//cost -> array[3*tuplesLength]
//empty := (array[3*tuplesLength] == INT_MAX)

void Tuple::SetTuplesIntSize(int numAct){
	Tuple::tuplesLength = numAct;
	Tuple::tuplesIntSize = 3 * numAct + 1;
}

int Tuple::GetCostFromTupleArray(int * tupleArray){
	return (tupleArray[3 * Tuple::tuplesLength] == -1) ? INT_MAX : tupleArray[3 * Tuple::tuplesLength];
}

Tuple::Tuple(){

	if (Tuple::tuplesLength == 0){
		perror("En Tuple::Tuple() - Intento de crear una tupla sin fijar el tamanio con anterioridad");
		exit (EXIT_FAILURE);
	}

	this->array = new int[Tuple::tuplesIntSize];
	this->array[3 * Tuple::tuplesLength] = -1;

}

Tuple::Tuple(int arraySize, int * array) {

	if (Tuple::tuplesLength == 0){
		perror("En Tuple::Tuple(int,int*) - Intento de crear una tupla sin fijar el tamanio con anterioridad");
		exit(EXIT_FAILURE);
	}else if (Tuple::tuplesIntSize != arraySize){
		perror("En Tuple::Tuple(int,int*) - Intento de crear una tupla con primer argumento distinto a Tuple::tuplesIntSize");
		exit (EXIT_FAILURE);
	}

	this->array = new int[Tuple::tuplesIntSize];
	memcpy(this->array, array, sizeof(int) * Tuple::tuplesIntSize);

}

Tuple::Tuple(Tuple * tuple) {

	this->array = new int[Tuple::tuplesIntSize];
	memcpy(this->array, tuple->array, sizeof(int) * Tuple::tuplesIntSize);

}

Tuple::~Tuple() {

	delete [] this->array;
}

bool Tuple::empty(){

	return (this->array[3 * Tuple::tuplesLength] == -1);
}

int * Tuple::getArray() {
	return this->array;
}

int * Tuple::modes() {
	return this->array;
}

int Tuple::modes(int act) {
	return this->array[act];
}

int Tuple::times(int act) {
	return this->array[Tuple::tuplesLength + act];
}

int Tuple::partialTimes(int act){
	return this->array[2 * Tuple::tuplesLength + act];
}

int Tuple::cost() {
	return this->empty() ? INT_MAX : this->array[3 * Tuple::tuplesLength];
}

void Tuple::modes(int act, int m) {
	this->array[act] = m;
}

void Tuple::times(int act, int t) {
	this->array[Tuple::tuplesLength + act] = t;
}

void Tuple::partialTimes(int act, int t){
	this->array[2 * Tuple::tuplesLength + act] = t;
}

void Tuple::cost(int c) {
	this->array[3 * Tuple::tuplesLength] = c;
}

void Tuple::print(){
	if (this->empty()){
		printf("The tuple is empty!!\n");
		return;
	}

	int numActs = Tuple::tuplesLength;
	int * modes = this->array;
	int * times = &this->array[Tuple::tuplesLength];

	printf("Activity\t\tMode\t\tTime\n--------\t\t----\t\t----\n\n");

	for(int act = 0; act < numActs; act++){

		printf("    %d    \t\t  %d  \t\t  %d  \n",act,modes[act],times[act]);

	}
}

